package com.ruoyi.socket.discard.time.client;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;

import java.util.Date;

@ChannelHandler.Sharable                                //1
public class TimeClientHandler extends
        ChannelInboundHandlerAdapter {

    private ByteBuf buf;


    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", //2
                CharsetUtil.UTF_8));
    }


    // 1.ChannelHandler 有2个生命周期的监听方法：handlerAdded()和 handlerRemoved()。
    // 你可以完成任意初始化任务只要他不会被阻塞很长的时间。
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        buf = ctx.alloc().buffer(4);
        // (1) 首先，所有接收的数据都应该被累积在 buf 变量里。
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        buf.release();
        // (1)
        buf = null;
    }

    /*@Override
    public void channelRead(ChannelHandlerContext ctx,
                             Object msg) {

        ByteBuf m = (ByteBuf) msg;
        buf.writeBytes(m); // (2)
        m.release();
        // 3.然后，处理器必须检查 buf 变量是否有足够的数据，在这个例子中是4个字节，然后处理实际的业务逻辑。
        // 否则，Netty 会重复调用channelRead() 当有更多数据到达直到4个字节的数据被积累。

        if (buf.readableBytes() >= 4) { // (3)
            long currentTimeMillis = (buf.readUnsignedInt() - 2208988800L) * 1000L;
            System.out.println(new Date(currentTimeMillis));
            //ctx.close();
        }
        System.out.println("Client received: " + buf.toString(CharsetUtil.UTF_8));    //3
    }*/

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf m = (ByteBuf) msg; // (1)
        try {
            long currentTimeMillis = (m.readUnsignedInt() - 2208988800L) * 1000L;
            System.out.println(new Date(currentTimeMillis));
            ctx.close();
        } finally {
            m.release();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx,
                                Throwable cause) {                    //4
        cause.printStackTrace();
        ctx.close();
    }
}